Web Worker 概述

众所周知,浏览器中的 JavaScript 是单线程的(诸多考量,其一是防止多个线程操作 DOM,造成线程安全问题)。

HTML5 提出的 Web Worker 支持多线程处理功能,因此可以充分利用多核 CPU 带来的优势,将耗时长的任务分配给 Web Worker 运行,从而避免了有时页面反应迟缓,甚至假死的现象。

使用这个 API,用户可以很容易的创建在后台运行的线程,这个线程被称之为 Worker。如果将耗费较长时间的处理交给后台来执行,则对用户在前台页面中执行的操作没有影响。

Web Worker 的特点如下:

除了上述的优点,Web Worker 本身也具有一定局限性的,具体如下:

目前来看,Web Worker 的浏览器兼容性还是很不错的,基本得到了主流浏览器的一致支持。

![[Pasted image 20240320200802.png]]

使用示例

Web Worker 属性和方法:

例如:

// 在 Worker 中导入 3 个 JavaScript 脚本  
importScripts("a.js", "b.js", "c.js");

Web Worker 的使用方法非常简单,只需要创建一个 Web Worker 对象,并传入希望执行的 JavaScript 文件 URL 地址即可。这里传入的 JavaScript 的 URL 可以是相对或者绝对路径,只要是相同的协议,主机和端口即可。

之后在页面中设置一个事件监听器,用来监听由 Web Worker 对象发来的消息。

如果想要在页面与 Web Worker 之间建立通信,数据需要通过 postMessage() 方法来进行传递。

如果想获取 Worker 进程的返回值,可以通过 onmessage 属性来绑定一个事件处理程序。

Web Worker 不能自行终止,但是能够被启用它们的页面所终止。调用 terminate() 函数可以终止后台进程。被终止的 Web Worker 将不再响应任何消息或者执行任何其他运算。

终止之后,Worker 不能被重新启动,但是可以使用同样的 URL 创建一个新的 Worker。

// 创建 Worker
const worker = new Worker('./worker.js')

// 主线程通过监听 message 获取 Worker 传递过来的消息
worker.onmessage = function (event) {
	console.log('来自 Worker 的消息', event.data)
}

// 主线程通过 postMessage 给 Worker 传递消息
worker.postMessage({ msg: 'ok 吗?' })

worker.js

// self、this、globalThis 都是全局对象,也可以不写
self.onmessage = function (e) {
  if (e.data?.msg === 'ok 吗?') {
    postMessage({ msg: '木问题!' })
  }
}

WorkerSharedWorker

Web Worker 可分为两种类型:

[[006.跨标签页通信#SharedWorker 定时器轮询|使用 SharedWorker 实现跨标签页通信]]